﻿using Microsoft.Exchange.WebServices.Data;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace TicketProcessingService
{
    public class SendEMail
    {
        public void SendMail()
        {
            NameValueCollection appSettings = ConfigurationManager.AppSettings;
            ExchangeService exchService = null;
            string exchVer = appSettings["ExVer"];
            #region Switch for exchange server type
            switch (exchVer)
            {
                case "Exchange 2007 SP1":
                    exchService = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
                    break;
                case "Exchange 2010":
                    exchService = new ExchangeService(ExchangeVersion.Exchange2010);
                    break;
                case "Exchange 2010 SP1":
                    exchService = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
                    break;
                case "Exchange 2010 SP2":
                    exchService = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
                    break;
                case "Exchange 2013":
                    exchService = new ExchangeService(ExchangeVersion.Exchange2013);
                    break;
                default:
                    break;
            }
            #endregion
            //ExchangeService exchService = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
            string UName = appSettings["HelpDeskUser"];
            if (UName.Contains('@'))
            {
                char chSep = '@';
                string[] arrStr = UName.Split(chSep);
                UName = arrStr[0];
            }
            string pwd = appSettings["HelpDeskPassword"];
            string Domain = appSettings["Domain"];
            WebCredentials credentials = new WebCredentials(UName, pwd, Domain);

            exchService.Credentials = credentials;
            string ExhName = appSettings["ExchServerName"];
            exchService.Url = new Uri("https://" + ExhName + "/EWS/Exchange.asmx");
            try
            {
                SearchFilter.IsEqualTo restriction = new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
                ServicePointManager.ServerCertificateValidationCallback = this.CertificateValidationCallBack;

                FindItemsResults<Item> AllUnreadEmails = exchService.FindItems(WellKnownFolderName.Inbox, restriction, new ItemView(int.MaxValue));
                foreach (Item item in AllUnreadEmails.Items)
                {
                    //init mail properties
                    ExtendedPropertyDefinition htmlBodyProperty = new ExtendedPropertyDefinition(0x1013, MapiPropertyType.Binary);
                    PropertySet propertySet = new PropertySet(BasePropertySet.FirstClassProperties, htmlBodyProperty);

                    //load message with its properties
                    EmailMessage message = EmailMessage.Bind(exchService, item.Id, propertySet);
                    string collection = appSettings["Collection"];
                    string project = appSettings["Project"];
                    this.CreateTicket(collection, project, message.Subject, message.Body.Text,UName, pwd, Domain);
                    message.IsRead = true;
                    message.Update(ConflictResolutionMode.AlwaysOverwrite);
                    //MessageBox.Show("Ticket Created and message read");
                }
            }
            catch (Exception ex)
            {
                string strEventSource = "Custom TFS Event Log";
                if (!EventLog.SourceExists(strEventSource)) 
                    EventLog.CreateEventSource(strEventSource,strEventSource);
                EventLog TfsLog = new EventLog(strEventSource, strEventSource);
                TfsLog.Source = strEventSource;
                TfsLog.Log = strEventSource;
                Console.WriteLine("Exception Message: " + ex.Message);
            }
        }
        private  bool CertificateValidationCallBack(
                    object sender,
                    System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                    System.Security.Cryptography.X509Certificates.X509Chain chain,
                    System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }
            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            {
                if (chain != null && chain.ChainStatus != null)
                {
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    {
                        if ((certificate.Subject == certificate.Issuer) &&
                                           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        {
                            // Self-signed certificates with an untrusted root are valid. 
                            continue;
                        }
                        else
                        {
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            {
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                return false;
                            }
                        }
                    }
                }
                // When processing reaches this line, the only errors in the certificate chain are 
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange server installations, so return true.
                return true;
            }
            else
            {
                // In all other cases, return false.
                return false;
            }
        }
        private void CreateTicket(string collection, string project, string Subject, string BodyText, string uName, string passwd, string domain)
        {
            string _uri = "http://" + Environment.MachineName + ":8080/tfs/" + collection;
            TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri(_uri), new NetworkCredential(uName,passwd,domain));
            WorkItemStore store = tpc.GetService<WorkItemStore>() as WorkItemStore;
            Project teamproject = store.Projects[project];
            WorkItem wi = new WorkItem(teamproject.WorkItemTypes["Ticket"]);
            wi.Title = Subject;
            wi.Description = BodyText;
            wi.Fields["SSGS.MyEfforts"].Value = 10;
            //wi.Fields["System.AssignedTo"].Value = "Subodh";
            wi.Save();
        }
    }
}
